package demo06Exception;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:咭咭熊
 * Date:2021 - 09 - 24
 * Time:10:31
 */
import java.util.Scanner;

/***
 * 六.异常：
 * 异常体系结构：
 *
 * 1.Throwable
 * （1）Error
 * （2）Exception
 *
 * 2.Exception
 * (1)IoException
 * (2)ClassNotFoundException
 * (3)CloneNotSupporetException
 * 前三个属于编译时异常（受查）
 * (4)Runntime Exception——运行时异常（非受查异常）
 *
 * 3.catch只能捕获对应的异常
 *
 * 4.异常处理流程：
 * （1）程序先执行try中的代码
 * （2）如果try中的代码出现异常，就会结束try中的代码，查看是否匹配catch中捕获的异常类型；
 * （3）如果找到匹配的异常类型，就会执行catch中的代码；
 * （4）如果没有找到匹配的异常类型，就会异常向上传递到上层调用者；
 * （5）无论是否找到匹配的异常类型，finally中的代码都会被执行到（在该方法结束之前）；
 * （6）如果上层调用者也没有处理异常，就会继续向上传递；
 * （7）一直到main方法也没有合适的代码处理异常，就会交给JVM进行处理。此时程序就会异常终止；
 *
 * 5.抛出异常
 * （1）使用内置类抛出异常；
 * （2）手动抛出异常：使用throw关键字；
 * （3）throws:声明异常
 *
 */
class Person implements  Cloneable{
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
//继承自RuntimeException——运行时异常
class MyException01 extends RuntimeException{//自定义异常继承自RuntimeException

    private String message;

    public MyException01(String message) {
        super(message);
    }
}

//继承自Exception——编译时异常
class MyException02 extends Exception{//自定义异常继承自RuntimeException

    private String message;

    public MyException02(String message) {
        super(message);
    }
}
public class MyException {
    /***
     * 11.编译时异常
     * @param args
     */
    public static void main(String[] args) {
        int a= 2;
        try{
            if(a == 10){
                throw new MyException02("发生了编译时异常！");
            }else{
                throw new MyException02("a 不等于10");
            }
        }catch(MyException02 myException02){
            myException02.printStackTrace();
        }
    }

    /***
     * 10.运行时异常
     * @param args
     */
    public static void main10(String[] args) {
        try{
            throw new MyException01("MyException!");
        }catch(MyException01 myException01){
            myException01.printStackTrace();
        }
    }

    /***
     * 9.自定义异常
     * @param args
     */
    public static void main9(String[] args) {
        try{
            //构造异常传递的参数——就是最后打印异常的描述信息
            throw new ArithmeticException("发生了异常！");
        }catch (ArithmeticException e){
            e.printStackTrace();
        }
    }


    //8.使用throw关键字实现手动抛出异常
    //throws:声明异常
    public static void func4(int y)throws ArithmeticException{
        if(y == 0){
            throw new ArithmeticException();
        }
        System.out.println(10 / y);
    }
    public static void main8(String[] args) {
        /*func4(0);*/
        try{
            func4(0);
        }catch(ArithmeticException e){
            e.printStackTrace();
        }
    }
    public static int func2(){
        try{
            int ret = 10 / 3;
            return  ret;
        }catch(ArithmeticException e){
            e.printStackTrace();
        }finally{//建议：不要在finally当中写return
            return  10;
        }
    }
    public static void main7(String[] args) {
        System.out.println(func2());//10
    }

    public static void main6(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        try{
            System.out.println(10 / n);
        }catch(ArithmeticException e){
            e.printStackTrace();
        }finally{//finally部分用于关闭资源
            sc.close();
        }
        System.out.println("end");
    }

    //无论是否存在异常，finally中的代码一定会被执行到
    //finally部分：释放资源
    public static void main5(String[] args) {
        try{
            System.out.println(10 / 0);

        }catch(ArithmeticException e){
            e.printStackTrace();
        }finally{//finally的作用：释放资源
            System.out.println("不管是否会发生异常，一定会执行finally部分！");
        }
        System.out.println("end");
    }
    //Exception 是所有异常类的父类：使用Exception捕获所有类型的异常
    public static void main4(String[] args) {
        int[] arr = {1,2,3};
        System.out.println("before");
        try{
            System.out.println(arr[100]);

        }catch(Exception e){
            e.printStackTrace();
            System.out.println("捕获了数组越界异常！");
        }
        System.out.println("end");
    }
    public static void main3(String[] args) {
        int[] arr = {1,2,3};
        System.out.println("before");
        try{
            System.out.println(arr[100]);

        }catch(NullPointerException | ArrayIndexOutOfBoundsException e){
            e.printStackTrace();
            System.out.println("捕获了数组越界异常！");
        }
        System.out.println("end");
    }

    public static void main2(String[] args) {
        int[] arr = {1,2,3};
        System.out.println("before");
        try{
            System.out.println(arr[100]);

        }catch(NullPointerException e){
            e.printStackTrace();
        }catch(ArrayIndexOutOfBoundsException e){
            System.out.println("捕获了数组越界异常！");
        }
        System.out.println("end");
    }

    public static void main1(String[] args) {
/*        Person person = new Person();
        person.clone();//运行时异常（受查异常）*/

        try {//可能会出现异常的代码
            System.out.println(10 / 0);
        }catch(ArithmeticException e){//处理异常
            e.printStackTrace();
            System.out.println("hahha");
        }
        //如果使用try处理了异常，那么程序会继续执行
        //如果不处理，那么这个异常就会交给JVM进行处理
        //一旦交给JVM进行处理异常，那么程序将异常终止，且不会继续执行
        System.out.println("hahhah");
    }
}
